﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using UnityEngine;

public static class SerializationExtension
{
    private static BinaryFormatter bf = new BinaryFormatter();

    public static bool CheckSerializable(this System.Type type)
    {
        if (type.IsGenericType)
        {
            System.Type[] genericArguments = type.GetGenericArguments();
            for (int i = 0; i < genericArguments.Length; i++)
            {
                if (!genericArguments[i].CheckSerializable())
                {
                    return false;
                }
            }
        }
        return (type.IsSerializable || typeof(ISerializable).IsAssignableFrom(type));
    }

    public static object DeserializeBytes(byte[] bytes)
    {
        MakeIosSupport();
        using (MemoryStream stream = new MemoryStream(bytes))
        {
            return bf.Deserialize(stream);
        }
    }

    public static T DeserializeFile<T>(string filePath)
    {
        if (!File.Exists(filePath))
        {
            throw new InvalidOperationException("File " + filePath + " is not existed");
        }
        MakeIosSupport();
        T local = default(T);
        using (FileStream stream = File.OpenRead(filePath))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            local = (T) formatter.Deserialize(stream);
            stream.Close();
        }
        return local;
    }

    [DebuggerHidden]
    public static IEnumerator DeserializeFile<T>(string url, Action<T> resultCallback)
    {
        return new <DeserializeFile>c__Iterator2A<T> { url = url, resultCallback = resultCallback, <$>url = url, <$>resultCallback = resultCallback };
    }

    public static T DeserializeFromPlayerPrefsBytes<T>(string prefKey)
    {
        MakeIosSupport();
        string s = PlayerPrefs.GetString(prefKey, string.Empty);
        if (s != string.Empty)
        {
            object obj2 = null;
            using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(s)))
            {
                obj2 = bf.Deserialize(stream);
            }
            if (obj2 is T)
            {
                return (T) obj2;
            }
        }
        return default(T);
    }

    public static T DeserializeFromXmlString<T>(string value)
    {
        MakeIosSupport();
        object obj2 = null;
        StringReader textReader = new StringReader(value);
        try
        {
            obj2 = new XmlSerializer(typeof(T)).Deserialize(textReader);
        }
        catch (Exception exception)
        {
            UnityEngine.Debug.LogError(exception);
        }
        finally
        {
            if (textReader != null)
            {
                textReader.Dispose();
            }
        }
        return (T) obj2;
    }

    private static void MakeIosSupport()
    {
    }

    public static byte[] SerializeToBytes(object obj)
    {
        MakeIosSupport();
        using (MemoryStream stream = new MemoryStream())
        {
            bf.Serialize(stream, obj);
            return stream.GetBuffer();
        }
    }

    public static void SerializeToPlayerPrefsBytes(string prefKey, object obj)
    {
        MakeIosSupport();
        using (MemoryStream stream = new MemoryStream())
        {
            bf.Serialize(stream, obj);
            string str = Convert.ToBase64String(stream.ToArray());
            PlayerPrefs.SetString(prefKey, str);
        }
    }

    public static string SerializeToXmlString(object obj)
    {
        MakeIosSupport();
        string str = null;
        StringWriter writer = new StringWriter();
        try
        {
            new XmlSerializer(obj.GetType()).Serialize((TextWriter) writer, obj);
            str = writer.ToString();
        }
        catch (Exception exception)
        {
            UnityEngine.Debug.LogError(exception);
        }
        finally
        {
            if (writer != null)
            {
                writer.Dispose();
            }
        }
        return str;
    }

    public static void SerializeToXmlStringFile(object obj, string path)
    {
        MakeIosSupport();
        string str = SerializeToXmlString(obj);
        if (!string.IsNullOrEmpty(str))
        {
            using (StreamWriter writer = new StreamWriter(path))
            {
                writer.WriteLine(str);
                writer.Close();
            }
        }
    }

    [CompilerGenerated]
    private sealed class <DeserializeFile>c__Iterator2A<T> : IDisposable, IEnumerator, IEnumerator<object>
    {
        internal object $current;
        internal int $PC;
        internal Action<T> <$>resultCallback;
        internal string <$>url;
        internal BinaryFormatter <bf>__2;
        internal MemoryStream <ms>__1;
        internal WWW <www>__0;
        internal Action<T> resultCallback;
        internal string url;

        [DebuggerHidden]
        public void Dispose()
        {
            this.$PC = -1;
        }

        public bool MoveNext()
        {
            uint num = (uint) this.$PC;
            this.$PC = -1;
            switch (num)
            {
                case 0:
                    if (this.url == null)
                    {
                        throw new InvalidOperationException("Url is null");
                    }
                    if (!typeof(T).CheckSerializable())
                    {
                        throw new InvalidOperationException("A serializable Type is required");
                    }
                    SerializationExtension.MakeIosSupport();
                    if (!this.url.Contains("://"))
                    {
                        throw new InvalidOperationException(this.url + " not is a url.");
                    }
                    this.<www>__0 = new WWW(this.url);
                    this.$current = this.<www>__0;
                    this.$PC = 1;
                    return true;

                case 1:
                    if (!string.IsNullOrEmpty(this.<www>__0.error))
                    {
                        UnityEngine.Debug.LogWarning(this.<www>__0.error);
                        break;
                    }
                    this.<ms>__1 = new MemoryStream(this.<www>__0.bytes, 0, this.<www>__0.bytes.Length);
                    try
                    {
                        this.<bf>__2 = new BinaryFormatter();
                        this.resultCallback((T) this.<bf>__2.Deserialize(this.<ms>__1));
                    }
                    finally
                    {
                        if (this.<ms>__1 != null)
                        {
                            this.<ms>__1.Dispose();
                        }
                    }
                    break;

                default:
                    goto Label_0151;
            }
            this.$PC = -1;
        Label_0151:
            return false;
        }

        [DebuggerHidden]
        public void Reset()
        {
            throw new NotSupportedException();
        }

        object IEnumerator<object>.Current
        {
            [DebuggerHidden]
            get
            {
                return this.$current;
            }
        }

        object IEnumerator.Current
        {
            [DebuggerHidden]
            get
            {
                return this.$current;
            }
        }
    }
}

